package org.example.network;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Demo2Talker {

    private final InputStream inputStream;
    private final OutputStream outputStream;
    private Socket socket;
    private String name;
    private Scanner scanner = new Scanner(System.in);

    private String recvFileDir = "E:\\录屏\\154\\0806";

    public Demo2Talker(Socket socket, String name) throws IOException {
        this.socket = socket;
        this.name = name;
        this.inputStream = socket.getInputStream();
        this.outputStream = socket.getOutputStream();
    }

    /**
     * 1. 如何将文件发送过去: 使用流读入文件, 发送给对方
     * 2. 如何区分文字消息和文件流, 发送信息之前, 先发送类别: msg, file
     * 3. 接收文件默认保存到指定目录
     */
    public void recv() {
        while (true) {
            try {
                byte[] bytes = new byte[1024];
                int count;
                count = inputStream.read(bytes);
                String type = new  String(bytes, 0, count);
                if("msg".equals(type)){
                    count = inputStream.read(bytes);
                    String msg = new  String(bytes, 0, count);
                    System.out.println(name + ": " + msg);
                } else if("file".equals(type)){
                    // 读取文件名
                    count = inputStream.read(bytes);
                    String filename = new String(bytes, 0, count);
                    System.out.println(name + ": 接收到文件" + filename);
                    count = inputStream.read(bytes);
                    String lengthStr = new String(bytes, 0, count);
                    System.out.println(name + ": 接收到文件大小" + lengthStr);
                    long length = Long.parseLong(lengthStr);
                    // 读取文件内容
                    String savePath = recvFileDir + File.separator + filename;
                    File file = new File(savePath);
                    // 定义计数器
                    long readLength = 0;
                    try(FileOutputStream fos = new FileOutputStream(file)) {
                        while (readLength < length) {
                            count = inputStream.read(bytes);
                            fos.write(bytes, 0, count);
                            readLength += count;
                        }
                    }
                    System.out.println(name + ": 文件接收完成: " + filename);
                } else {
                    System.out.println("未知类型: " + type);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void send() {
        while (true) {
            try {
//                System.out.print("请输入: ");
//                String msg = scanner.nextLine();
//                outputStream.write(msg.getBytes());
                // 先让用户输入: msg 或 file
                System.out.print("请输入类型: ");
                String type = scanner.nextLine();
                // 发送类型
                outputStream.write(type.getBytes());
                if("msg".equals(type)) {
                    // 发送文字
                    System.out.print("请输入文字消息: ");
                    String msg = scanner.nextLine();
                    outputStream.write(msg.getBytes());
                } else if("file".equals(type)) {
                    // 发送文件
                    System.out.print("请输入文件路径: ");
                    String path = scanner.nextLine();
                    File file = new File(path);
                    if(!file.exists()) {
                        System.out.println("文件不存在");
                        continue;
                    }
                    // 发送文件名
                    outputStream.write(file.getName().getBytes());
                    // 发送文件大小
                    outputStream.write((file.length()+"").getBytes());
                    // 发送文件内容
                    try(InputStream inputStream = new FileInputStream(file)) {
                        byte[] bytes = new byte[1024];
                        int count;
                        while ((count = inputStream.read(bytes)) != -1) {
                            outputStream.write(bytes, 0, count);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 群发功能
 * 1. 可以发送文字或文件到所有的客户端(群发)
 * 2. 可以选择客户端发送文件或文字(私发)
 *
 * 实现方式:
 * 1. 方式一: 每一个客户端内部记录所有的连接上的其他客户端, 会产生大量的 socket 连接
 * 2. 方式二: 建立一个服务器, 每一个客户端都连上服务器, 客户端之间不直接连接, 群发通过服务器实现群发
 *
 *
 *  问题:
 *  一旦后接收一次文件, 那么后续的文字消息和文件消息都无法接收了
 */


/**
 * 如何更高效的发送文件: 可以将文件压缩再发送
 * 压缩文件为zip, 发送,  解压还原 7z, gzip, rar...
 * 要告知接收方压缩, zip, rar, 未压缩...
 * 压缩是可选参数
 * 如果浏览器, 那么还要知道接收的文件的类型, 图片, 视频, js
 * 告知接收端文件类型, servlet content-type
 *
 * 发送文件附带的参数:
 * 必填参数(文件名, 大小),
 * 可选参数(压缩, 类型)
 *
 * 给服务端的参数:
 * filename=文件名, size=大小, compress=压缩, type=类型
 *
 */